/**
 * 抽象工厂
 * 对拓展开放 对修改封闭
 * 定义: 围绕一个超级工厂创建其他工厂
 * 四个关键角色:
 * 1.抽象工厂(抽象类 它不能被用于生成具体实例)
 * 用于声明最终目标产品的共性
 * 2.具体工厂(用于生成产品族里的一个具体的产品)
 * 继承自抽象工厂 实习了抽象工厂里面的那些方法 用于创建具体的产品的类
 * 3.抽象产品(抽象类 它不能被用于生成具体实例) -> 本质上还是简单工厂？抽离共性
 * 具体产品类的共性各自抽离 便对应了各自的抽象产品类
 * 4.具体产品(于生成产品族里的一个具体的产品所依赖的更细粒度的产品)
 * 用于生成具体的一个产品
 */

// 抽象工厂角色
class MobilePhoneFactory {
    // 提供操作系统的接口
    createOS(){
        throw new Error("抽象工厂方法不允许直接调用，你需要将我重写！");
    }
    // 提供硬件的接口
    createHardWare(){
        throw new Error("抽象工厂方法不允许直接调用，你需要将我重写！");
    }
}

// 定义操作系统这类产品的抽象产品类
class OS {
    controlHardWare() {
        throw new Error('抽象产品方法不允许直接调用，你需要将我重写！');
    }
}

// 定义具体操作系统的具体产品类
class AndroidOS extends OS {
    // 重写抽象产品类方法
    controlHardWare() {
        console.log('我会用安卓的方式去操作硬件')
    }
}
// 定义具体操作系统的具体产品类
class AppleOS extends OS {
    // 重写抽象产品类方法
    controlHardWare() {
        console.log('我会用🍎的方式去操作硬件')
    }
}

// 定义手机硬件这类产品的抽象产品类
class HardWare {
    // 手机硬件的共性方法，这里提取了“根据命令运转”这个共性
    operateByOrder() {
        throw new Error('抽象产品方法不允许直接调用，你需要将我重写！');
    }
}

// 定义具体硬件的具体产品类
class QualcommHardWare extends HardWare {
    operateByOrder() {
        console.log('我会用高通的方式去运转')
    }
}
// 定义具体硬件的具体产品类
class MiWare extends HardWare {
    operateByOrder() {
        console.log('我会用小米的方式去运转')
    }
}

// 具体工厂角色
// 具体工厂继承自抽象工厂
class FakeStarFactory extends MobilePhoneFactory {
    createOS() {
        // 提供安卓系统实例
        return new AndroidOS()
    }
    createHardWare() {
        // 提供高通硬件实例
        return new QualcommHardWare()
    }
}
// 具体工厂角色
class IponeFactory extends MobilePhoneFactory {
    createOS() {
        // 提供ios系统实例
        return new AppleOS()
    }
    createHardWare() {
        // 提供高通硬件实例
        return new QualcommHardWare()
    }
}

// 这是我的手机
const myPhone = new FakeStarFactory()
// 让它拥有操作系统
const myOS = myPhone.createOS()
// 让它拥有硬件
const myHardWare = myPhone.createHardWare()
// 启动操作系统(输出‘我会用安卓的方式去操作硬件’)
myOS.controlHardWare()
// 唤醒硬件(输出‘我会用高通的方式去运转’)
myHardWare.operateByOrder()

// 这是我的手机
const iphone = new IponeFactory()
// 让它拥有操作系统
iphone.myOS = iphone.createOS()
// 让它拥有硬件
iphone.myHardWare = iphone.createHardWare()
// 启动操作系统
iphone.myOS.controlHardWare()
// 唤醒硬件
iphone.myHardWare.operateByOrder()
console.log(iphone)